package com.example.androidstudy.moshi

import com.squareup.moshi.*
import java.lang.reflect.Type

class NullToEmptyStringAdapter() {
    @ToJson
    fun toJson(@NullToEmptyString value: String): String {
        return value
    }

    @FromJson
    @NullToEmptyString
    fun fromJson(reader: JsonReader): String? {
        println("NullToEmptyString")
        // com.squareup.moshi.JsonDataException: Expected a name but was NULL at path $.name
        val result = if (reader.peek() === JsonReader.Token.NULL) {
            reader.nextNull()
        } else {
            reader.nextString()
        }

        return result ?: ""
    }


}

@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class NullToEmptyString

class NullToEmptyListJsonAdapter(val delegate: JsonAdapter<List<Any>>?) :
    JsonAdapter<List<Any>>() {

    override fun fromJson(reader: JsonReader): List<Any>? {
        if (reader.peek() == JsonReader.Token.NULL) {
            reader.skipValue()
            return emptyList()
        }
        return delegate!!.fromJson(reader)
    }

    override fun toJson(writer: JsonWriter, value: List<Any>?) {
        checkNotNull(value) { "Wrap JsonAdapter with .nullSafe()." }
        delegate!!.toJson(writer, value)
    }

    companion object {
        val FACTORY = object : Factory {
            override fun create(
                type: Type,
                annotations: MutableSet<out Annotation>,
                moshi: Moshi
            ): JsonAdapter<*>? {
                if (annotations.isNotEmpty()) {
                    return null
                }
                if (Types.getRawType(type) != List::class.java) {
                    return null
                }
                val objectJsonAdapter = moshi.nextAdapter<List<Any>>(this, type, annotations)
                return NullToEmptyListJsonAdapter(objectJsonAdapter)

            }

        }
    }

}